package com.huaxin.hxmoduleworkorder.common;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;

import java.sql.*;
import java.util.List;
import java.util.Map;

@MappedTypes({List.class, Map.class, Object.class}) // 声明支持的 Java 类型（可选）
public class JsonTypeHandler<T> implements TypeHandler<T> {

    private static final ObjectMapper objectMapper = new ObjectMapper();
    private final TypeReference<T> typeReference;

    /**
     * 构造时传入具体类型，如：new JsonTypeHandler<>(new TypeReference<List<Map<String, Object>>>() {})
     */
    public JsonTypeHandler(TypeReference<T> typeReference) {
        this.typeReference = typeReference;
    }

    @Override
    public void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
        if (parameter == null) {
            ps.setNull(i, Types.VARCHAR);
        } else {
            try {
                String json = objectMapper.writeValueAsString(parameter);
                ps.setString(i, json);
            } catch (JsonProcessingException e) {
                throw new SQLException("Error converting object to JSON", e);
            }
        }
    }

    @Override
    public T getResult(ResultSet rs, String columnName) throws SQLException {
        String json = rs.getString(columnName);
        return parseJson(json);
    }

    @Override
    public T getResult(ResultSet rs, int columnIndex) throws SQLException {
        String json = rs.getString(columnIndex);
        return parseJson(json);
    }

    @Override
    public T getResult(CallableStatement cs, int columnIndex) throws SQLException {
        String json = cs.getString(columnIndex);
        return parseJson(json);
    }

    private T parseJson(String json) {
        if (json == null || json.trim().isEmpty()) {
            return null;
        }

        try {
            T result = objectMapper.readValue(json, typeReference);
            return result;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException("Error parsing JSON to " + typeReference.getType().getTypeName(), e);
        }
    }
}